package ar.com.cema.methodology.analyzer.ui.servlet.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import ar.com.cema.methodology.analyzer.model.Answer;
import ar.com.cema.methodology.analyzer.model.Methodology;
import ar.com.cema.methodology.analyzer.model.MethodologyAnswer;
import ar.com.cema.methodology.analyzer.model.Question;
import ar.com.cema.methodology.analyzer.model.Survey;
import ar.com.cema.methodology.analyzer.services.SurveyService;
import ar.com.cema.methodology.analyzer.ui.PageDirectory;
import ar.com.cema.methodology.analyzer.ui.ServiceLocator;

@WebServlet(name="SendAnsweredQuestionnaireServlet", urlPatterns = { ServiceLocator.ACTION_SEND_ANSWERS }) 
public class SendAnsweredQuestionnaireServlet extends ActionServlet {
	private static final long serialVersionUID = 677666319152485634L;

	@Autowired
	private SurveyService surveyService;
	
	private Log logger = LogFactory.getLog(SendAnsweredQuestionnaireServlet.class);
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		logger.info("SendAnsweredQuestionnaireServlet.doPost()");

		Survey survey = (Survey) request.getSession().getAttribute("survey");
		Set<Question> questions = survey.getQuestions();
		List<String> errors = new ArrayList<String>();
		
		if ( questions.size() > request.getParameterMap().size() ) {
			logger.info("[APP_ERROR]: No se contestaron todas las preguntas.");
			errors.add("In order to improve our database we would need you to complete all the answers with at least one option each. Thanks!");
			request.setAttribute("errors", errors);
			request.getServletContext().getRequestDispatcher(PageDirectory.SURVEY_QUESTIONNAIRE).forward(request, response);
			return;
		}
		
		try {
			String surveyId = request.getParameter("surveyId");
			survey.setId(Long.parseLong(surveyId));
			
			logger.info("Generating survey with id=" + surveyId);
			logger.info("Survey has " + questions.size() + " questions.");
			
			for (Question question : questions) {
				logger.info("Question [id=" + question.getId() + "] has value='" + question.getValue() + "' for variable[id=" + question.getVariable().getId() + "]");
				if (request.getParameterMap().containsKey(question.getId().toString())) {
					Answer answer = this.extractAnswerFrom(request, survey, question);
					survey.getAnswers().add(answer);
					logger.info("Answer add for question [id=" + question.getId() + "]");
				}
			}
		
			logger.info("Survey has " + survey.getAnswers().size() + " answers.");
			
			survey = surveyService.save(survey);
			request.getSession().setAttribute("survey", survey);
			request.getServletContext().getRequestDispatcher(PageDirectory.SURVEY_QUESTIONNAIRE_COMPLETED).forward(request, response);
			return;
		} catch (Exception e) {
			logger.error("Cause is " + e.getMessage());
			logger.error(e.getStackTrace());
			errors.add("Ups, something went wrong. We are sorry but it happens!");
			errors.add("Cause is: " + e);
			request.setAttribute("errors", errors);
			request.getServletContext().getRequestDispatcher(PageDirectory.SURVEY_QUESTIONNAIRE).forward(request, response);
			return;
		}
	}
	
	private Answer extractAnswerFrom(HttpServletRequest request, Survey survey, Question question) {
		String[] answersIds =  request.getParameterValues(question.getId().toString());
		
		Answer answer = new Answer();
		answer.setQuestion(question);
		answer.setSurvey(survey);
		answer.setMethodologiesAnswers(new TreeSet<MethodologyAnswer>());
		
		for (int i=0; i < answersIds.length; i++) {
			MethodologyAnswer methodologyAnswer = new MethodologyAnswer();
			methodologyAnswer.setMethodology(new Methodology(Long.parseLong(answersIds[i])));
			methodologyAnswer.setValue(question.getOptions().size() - i);
			methodologyAnswer.setAnswer(answer);
			methodologyAnswer.setVariable(question.getVariable());

			answer.getMethodologiesAnswers().add(methodologyAnswer);
		}
		return answer;
	}
	
	public void setSurveyService(SurveyService surveyService) {
		this.surveyService = surveyService;
	}
}
